#lang racket


(require "../base/main.rkt")

(provide 
 (struct-out primitive-type)
 (struct-out line-primitive-type)
 (struct-out surface-primitive-type)
 (struct-out solid-primitive-type)
 
 (struct-out align-type)
 
 (struct-out key-align-type)
 (struct-out center-key-align-type)
 (struct-out x-pos-key-align-type)
 (struct-out x-neg-key-align-type)
 (struct-out y-pos-key-align-type)
 (struct-out y-neg-key-align-type)
 (struct-out z-pos-key-align-type)
 (struct-out z-neg-key-align-type)
 
 (struct-out shape-align-type)
 (struct-out x-cen-shape-align-type)
 (struct-out x-pos-shape-align-type)
 (struct-out x-neg-shape-align-type)
 (struct-out y-cen-shape-align-type)
 (struct-out y-pos-shape-align-type)
 (struct-out y-neg-shape-align-type)
 (struct-out z-cen-shape-align-type)
 (struct-out z-pos-shape-align-type)
 (struct-out z-neg-shape-align-type)
 
 (struct-out loft-type)
 (struct-out auto-loft-type)
 (struct-out surface-loft-type)
 (struct-out solid-loft-type)
 
 (struct-out loft-fit-type)
 (struct-out ruled-loft-fit-type)
 (struct-out smooth-loft-fit-type)
 
 (struct-out on-type)
 (struct-out x-pos-on-type)
 (struct-out x-neg-on-type)
 (struct-out y-pos-on-type)
 (struct-out y-neg-on-type)
 (struct-out z-pos-on-type)
 (struct-out z-neg-on-type)
 
 (struct-out projection-type)
 (struct-out ortho-projection-type)
 (struct-out perspective-projection-type)
 
 (struct-out render-type)
 (struct-out draft-render-type)
 (struct-out presentation-render-type)
 
 (struct-out scaling-type)
 (struct-out center-scaling-type)
 (struct-out origin-scaling-type)
 
 (struct-out section-type)
 (struct-out auto-section-type)
 (struct-out line-section-type)
 (struct-out surface-section-type)
 
 (struct-out spline-type)
 (struct-out auto-spline-type)
 (struct-out tangent-spline-type)
 
 (struct-out view-type)
 (struct-out auto-view-type)
 (struct-out manual-view-type)
 
 (struct-out view-style)
 (struct-out wireframe-view-style)
 (struct-out realistic-view-style)
 
 generate-curve-points
 (struct-out functional-curve))


; primitive-type

(struct primitive-type ())
(struct line-primitive-type primitive-type ())
(struct surface-primitive-type primitive-type ())
(struct solid-primitive-type primitive-type ())


; align-type

(struct align-type ())

(struct key-align-type align-type ())
(struct center-key-align-type key-align-type ())
(struct x-pos-key-align-type key-align-type ())
(struct x-neg-key-align-type key-align-type ())
(struct y-pos-key-align-type key-align-type ())
(struct y-neg-key-align-type key-align-type ())
(struct z-pos-key-align-type key-align-type ())
(struct z-neg-key-align-type key-align-type ())

(struct shape-align-type align-type ())
(struct x-cen-shape-align-type shape-align-type ())
(struct x-pos-shape-align-type shape-align-type ())
(struct x-neg-shape-align-type shape-align-type ())
(struct y-cen-shape-align-type shape-align-type ())
(struct y-pos-shape-align-type shape-align-type ())
(struct y-neg-shape-align-type shape-align-type ())
(struct z-cen-shape-align-type shape-align-type ())
(struct z-pos-shape-align-type shape-align-type ())
(struct z-neg-shape-align-type shape-align-type ())

; /align-type


; loft-type

(struct loft-type ())
(struct auto-loft-type loft-type ())
(struct surface-loft-type loft-type ())
(struct solid-loft-type loft-type ())

; /loft-type


; loft-fit-type

(struct loft-fit-type ())
(struct ruled-loft-fit-type loft-fit-type ())
(struct smooth-loft-fit-type loft-fit-type ())

; /loft-fit-type


; on-type

(struct on-type ())
(struct x-pos-on-type on-type ())
(struct x-neg-on-type on-type ())
(struct y-pos-on-type on-type ())
(struct y-neg-on-type on-type ())
(struct z-pos-on-type on-type ())
(struct z-neg-on-type on-type ())


; projection type

(struct projection-type ())
(struct ortho-projection-type projection-type ())
(struct perspective-projection-type projection-type (lens))


; render type

(struct render-type ())
(struct draft-render-type render-type ())
(struct presentation-render-type render-type ())


; scaling type

(struct scaling-type ())
(struct center-scaling-type scaling-type ())
(struct origin-scaling-type scaling-type ())


; section type

(struct section-type ())
(struct auto-section-type section-type ())
(struct line-section-type section-type ())
(struct surface-section-type section-type ())


; spline type

(struct spline-type ())
(struct auto-spline-type spline-type ())
(struct tangent-spline-type spline-type (begin-tangent end-tangent))


; view-type

(struct view-type ())
(struct auto-view-type view-type (direction))
(struct manual-view-type view-type (center target))


; view-style

(struct view-style ())
(struct wireframe-view-style view-style ())
(struct realistic-view-style view-style ())


; adaptive parametric

(define (aproximately-colinear? p0 p1 p2 epsilon)
  (let ((a (distance p0 p1))
        (b (distance p1 p2))
        (c (distance p2 p0)))
    (< (triangle-area a b c) epsilon)))

(define (triangle-area a b c)
  (let ((s (/ (+ a b c) 2.0)))
    (sqrt (* s (- s a) (- s b) (- s c)))))

(define (adaptive-parametric fn t0 p0 t1 p1 dt epsilon)
  (let ((tm (/ (+ t0 t1) 2.0)))
    (let ((pm (fn tm)))
      (if (and (< (- t1 t0) dt)
               (aproximately-colinear? p0 pm p1 epsilon))
          (list p0 pm p1)
          (append (adaptive-parametric fn t0 p0 tm pm dt epsilon)
                  (cdr (adaptive-parametric fn tm pm t1 p1 dt epsilon)))))))


(define max-dt 0.5)
(define max-epsilon 0.0001)

(define (generate-curve-points fn t0 t1)
  (adaptive-parametric fn t0 (fn t0) t1 (fn t1) max-dt max-epsilon))


(struct functional-curve (fn t0 t1))